package com.mspbots.rule.exceptions.cw;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.mspbots.cw.request.TenantRuleDTO;
import com.mspbots.cw.request.TenantTicketDTO;
import com.mspbots.cw.request.TenantTimeEntryDTO;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * com.mspbots.rule.exceptions.timeentry.IncludingWords
 *
 * @author Jun Zhou
 * @date 12:42 2019/7/1
 **/
@Slf4j
@Rule(name = "IncludingWords", description = "Time log entry has “xxx” in it.")
public class IncludingWords extends CwBaseRule implements IcwBaseRule {


    private String word = "";

    @Condition
    @Override
    public boolean condition(@Fact(FACT) TenantTimeEntryDTO entry) {
        try {
            if (!setUserMapping(entry.getTenantUserId()) || super.checkMessage(entry)) {
                return false;
            }
            JsonNode params = JSONUtil.isNull(this.tenantRuleDTO.getRuleParams()) ?
                    this.tenantRuleDTO.getSysParams() : this.tenantRuleDTO.getRuleParams();
            Iterator<String> iterator = params.fieldNames();
            boolean include = false;
            while (iterator.hasNext()) {
                String fieldName = iterator.next();
                String fieldValue = params.get(fieldName).asText().toLowerCase();
                if (StringUtils.isEmpty(fieldValue)) {
                    continue;
                }
                include = include || entry.getDescription().toLowerCase().contains(fieldValue);
                if (include) {
                    word = params.get(fieldName).asText();
                    break;
                }
            }
            if (include && !ObjectUtils.isEmpty(entry.getExtend().get("chargeToId"))) {
                Map<String, Object> ticketsParams = Map.of("tenantId", entry.getTenantId(),
                        "cwId", entry.getExtend().get("chargeToId"));
                TenantTicketDTO tenantTicketDTO = this.coreClient.get("/tickets/detail", ticketsParams, TenantTicketDTO.class).block();
                if (tenantTicketDTO == null || StringUtils.isEmpty(tenantTicketDTO.getExtend().findPath("board"))) {
                    log.info("IncludingWords tenantTicketDTO_is null or status is null {}", entry.getId());
                    return false;
                }
                return tenantTicketDTO.getExtend().findPath("board").get("name").asText().toLowerCase().indexOf("reactive") > -1;
            }

//            log.info("including words : {}", entry.getCwTid());
//            return fireDrools(entry, tenantRuleDTO);
        } catch (Exception e) {
            log.error("IncludingWords rule execute error [{}] : {}", e.getStackTrace()[0].getLineNumber(), e.getMessage());
            e.printStackTrace();
        }
        return false;
    }


    private boolean fireDrools(TenantTimeEntryDTO entry, TenantRuleDTO tenantRuleDTO) {
        String url = "http://mspbots-drools/trigger/rule/time_entry/fire";

        HashMap<String, Object> droolsParams = new HashMap<>(16);

        droolsParams.put("tenantId", tenantRuleDTO.getTenantId());
        droolsParams.put("ruleId", tenantRuleDTO.getRuleId());
        try {
            droolsParams.put("fact", this.objectMapper.writeValueAsString(entry.getExtend()));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> request = new HttpEntity<Map<String, Object>>(droolsParams, headers);


        try {
//            log.info("droolsParams : {}", droolsParams);
            JsonNode result = restTemplate.postForObject(url, request, JsonNode.class);
            log.info("result : {}", result);
            this.word = ObjectUtils.isEmpty(result.get("WORD")) ? "" : result.get("WORD").asText();
            return result.get("fire").asBoolean(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Action
    @Override
    public void action(@Fact(FACT) TenantTimeEntryDTO entry) {
        messages.setTimeEntryId(entry.getCwTid());
        Map params = new HashMap(16);
        params.put("WORD", styleParam(word));
        String message = getMessage(entry);
        if (message != null) {
            String msg = StrUtil.format(message, params);
            messages.setMessage(msg);
            insertMessage();
        }


    }


}
